/**
 * File: MapEntryBean.java
 * Created by: mhaimel
 * Created on: 17 Aug 2009
 * CVS:  $Id: MapEntryBean.java,v 1.1 2009/08/27 14:52:44 mhaimel Exp $
 */
package uk.ac.ebi.curtain.util.io;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import uk.ac.ebi.curtain.utils.file.maq.MaqFlag;
import uk.ac.ebi.curtain.utils.match.MatchDetails;
import uk.ac.ebi.velvet.model.Strand;

/**
 * @author mhaimel
 *
 */
public class MapEntryBean {
	private final AtomicInteger category = new AtomicInteger(0);
	private final AtomicReference<String> contigId = new AtomicReference<String>();
	private final AtomicReference<String> readId = new AtomicReference<String>();
	private final AtomicReference<MaqFlag> flag = new AtomicReference<MaqFlag>();
	private final AtomicInteger referenceLocation = new AtomicInteger(0);
	private final AtomicInteger readLocation = new AtomicInteger(0);
	private final AtomicInteger alignLength = new AtomicInteger(0);
	private final AtomicReference<Strand> readOrientation = new AtomicReference<Strand>();
	private final AtomicReference<Strand> alignOrientation = new AtomicReference<Strand>();
	private final AtomicInteger mapQual = new AtomicInteger(0);
	private final AtomicInteger semQual = new AtomicInteger(0);
	private final AtomicInteger altQual = new AtomicInteger(0);
	
	public MapEntryBean() {
	}

	public MapEntryBean(Integer category, String contigId, String readId, MaqFlag flag,
						int location, Strand readOrientation, Strand alignOrientation, 
						int mapQual, int semQual, int altQual, int alignLength) {
		super();
		this.category.set(category);
		this.contigId.set(contigId);
		this.readId.set(readId);
		this.flag.set(flag);
		this.referenceLocation.set(location);
		this.readOrientation.set(readOrientation);
		this.alignOrientation.set(alignOrientation);
		this.mapQual.set(mapQual);
		this.semQual.set(semQual);
		this.altQual.set(altQual);
		this.alignLength.set(alignLength);
	}

	public MapEntryBean(Integer category, MaqFlag flag, MatchDetails details) {
		this(
				category,
				details.getReference(),
				details.getReadId(),
				flag,
				details.getReferenceLocation(),
				details.getReadOrientation(),
				details.getAlignOrientation(),
				details.getQualitiesLength()>0?details.getQualities(0):0,
				details.getQualitiesLength()>1?details.getQualities(1):0,
				details.getQualitiesLength()>2?details.getQualities(2):0,
				details.getAlignLength()
		);
		this.readLocation.set(details.getReadLocation());
	}


	public String getContigId() {
		return contigId.get();
	}

	public void setContigId(String contigId) {
		this.contigId.set(contigId);
	}
	
	

	/**
	 * @return the category
	 */
	public Integer getCategory() {
		return category.get();
	}

	/**
	 * @param category the category to set
	 */
	public void setCategory(Integer category) {
		this.category.set(category);
	}

	public String getReadId() {
		return readId.get();
	}

	public void setReadId(String readId) {
		this.readId.set(readId);
	}

	public MaqFlag getFlag() {
		return flag.get();
	}

	public void setFlag(MaqFlag flag) {
		this.flag.set(flag);
	}

	public int getReferenceLocation() {
		return referenceLocation.get();
	}

	public void setReferenceLocation(int location) {
		this.referenceLocation.set(location);
	}	

	public int getReadLocation() {
		return readLocation.get();
	}

	public void setReadLocation(int location) {
		this.readLocation.set(location);
	}	

	public int getAlignLength() {
		return alignLength.get();
	}

	public void setAlignLength(int alignLength) {
		this.alignLength.set(alignLength);
	}


	public Strand getReadOrientation() {
		return readOrientation.get();
	}

	public void setReadOrientation(Strand readOrientation) {
		this.readOrientation.set(readOrientation);
	}

	public Strand getAlignOrientation() {
		return alignOrientation.get();
	}

	public void setAlignOrientation(Strand alignOrientation) {
		this.alignOrientation.set(alignOrientation);
	}
	
	/**
	 * @return the mapQual
	 */
	public int getMapQual() {
		return mapQual.get();
	}

	/**
	 * @param mapQual the mapQual to set
	 */
	public void setMapQual(int mapQual) {
		this.mapQual.set(mapQual);
	}

	/**
	 * @return the semQual
	 */
	public int getSemQual() {
		return semQual.get();
	}

	/**
	 * @param semQual the semQual to set
	 */
	public void setSemQual(int semQual) {
		this.semQual.set(semQual);
	}

	/**
	 * @return the altQual
	 */
	public int getAltQual() {
		return altQual.get();
	}

	/**
	 * @param altQual the altQual to set
	 */
	public void setAltQual(int altQual) {
		this.altQual.set(altQual);
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,ToStringStyle.SHORT_PREFIX_STYLE);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((alignOrientation == null) ? 0 : alignOrientation.hashCode());
		result = prime * result
				+ ((contigId == null) ? 0 : contigId.hashCode());
		result = prime * result + ((flag == null) ? 0 : flag.hashCode());
		result = prime * result + referenceLocation.get();
		result = prime * result + mapQual.get();
		result = prime * result + semQual.get();
		result = prime * result + altQual.get();
		result = prime * result + readLocation.get();
		result = prime * result + alignLength.get();
		result = prime * result + ((readId == null) ? 0 : readId.hashCode());
		result = prime * result
				+ ((readOrientation == null) ? 0 : readOrientation.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		MapEntryBean other = (MapEntryBean) obj;
		if (alignOrientation == null) {
			if (other.alignOrientation != null)
				return false;
		} else if (!alignOrientation.equals(other.alignOrientation))
			return false;
		if (contigId == null) {
			if (other.contigId != null)
				return false;
		} else if (!contigId.equals(other.contigId))
			return false;
		if (flag == null) {
			if (other.flag != null)
				return false;
		} else if (!flag.equals(other.flag))
			return false;
		if (referenceLocation.get() != other.referenceLocation.get())
			return false;
		if (readLocation.get() != other.readLocation.get())
			return false;
		if (alignLength.get() != other.alignLength.get())
			return false;
		if (mapQual.get() != other.mapQual.get())
			return false;
		if (semQual.get() != other.semQual.get())
			return false;
		if (altQual.get() != other.altQual.get())
			return false;
		if (readId.get() == null) {
			if (other.readId.get() != null)
				return false;
		} else if (!readId.equals(other.readId))
			return false;
		if (readOrientation == null) {
			if (other.readOrientation != null)
				return false;
		} else if (!readOrientation.equals(other.readOrientation))
			return false;
		return true;
	}
}
